import { Color, Matrix4, Vector3, Quaternion } from 'https://unpkg.com/three/build/three.module.js';
import { initShaders, ScaleLinear } from '../jsm/Utils.js';
import lib from '../jsm/ThreeLib.js';
import Poly from '../jsm/Poly3.js'
import Sky from '../jsm/Sky.js'
import ShapeGeo from '../jsm/ShapeGeo.js';
import Ground2D from '../jsm/Ground2D.js'

window.onload = function () {

    const backColor = new Color("rgba(0,0,0,1)");

    const canvas = document.getElementById("canvas");
    canvas.width = window.innerWidth;
    canvas.height = window.innerHeight;

    const gl = canvas.getContext("webgl");
    //开启颜色合成,才会有透明度的感觉
    gl.enable(gl.BLEND);
    gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);

    //初始化着色器
    initShaders(gl,
        document.querySelector("#vertexShader").innerText,
        document.querySelector("#fragmentShader").innerText);
    lib.clearCanvas(gl, new Color("rgba(0,0,0,1)"), 1);




    const endLength = 100;
    const interval = 2;
    const [minColor, maxColor] = [[51, 8, 103], [48, 207, 208]];


    /* x,z 方向的空间坐标极值 */
    const [minPosX, maxPosX, minPosZ, maxPosZ] = [
        -0.9, 0.9, -0.9, 0.9
    ]
    /* x,z 方向的弧度极值 */
    const [minAngX, maxAngX, minAngZ, maxAngZ] = [
        0, Math.PI * 4, 0, Math.PI * 2
    ]

    /* 比例尺：将空间坐标和弧度相映射 */
    const scalerX = ScaleLinear(minPosX, minAngX, maxPosX, maxAngX)
    const scalerZ = ScaleLinear(minPosZ, minAngZ, maxPosZ, maxAngZ)

    const glArr = cssToGl(createNodes(), maxPosX);

    const retArr = lib.planeNodeToTriangleOf3D(glArr, endLength / interval + 1);
    // const retArr = lib.planeNodeToLineOf3D(glArr, endLength / interval + 1);


    //创建颜色
    let colorArr = createColor(retArr.length / 3);
    //合并颜色
    let allArr = addData(retArr, 3, colorArr, 4);
    //合并大小
    allArr = addData(
        allArr,
        7,
        Array.from({ length: retArr.length }, () => 3),
        1);



    let poly = new Poly({
        gl: gl,
        arr: allArr,
        list: [
            { name: 'a_Position', size: 3, beginIndex: 0 },
            { name: 'a_Color', size: 4, beginIndex: 3 },
            { name: 'a_PointSize', size: 1, beginIndex: 7 },
        ]
    })



    var vm4 = new Matrix4().lookAt(
        new Vector3(0.2, 0.5, 1),
        new Vector3(0, 0, 0),
        new Vector3(0, 1, 0),
    );
    var mm4 = new Matrix4();
    // mm4.makeRotationY(0.5);


    let u_Vm4 = gl.getUniformLocation(gl.program, 'u_ViewMatrix');
    gl.uniformMatrix4fv(u_Vm4, false, vm4.elements);

    let u_Mm4 = gl.getUniformLocation(gl.program, 'u_ModelMatrix');
    gl.uniformMatrix4fv(u_Mm4, false, mm4.elements);

    updateY(allArr);
    poly.updateBuffer();
    poly.draw(["LINES"]);



    let offset = 0;
    (function ani() {
        offset += 0.02
        updateY(allArr, offset);
        poly.updateBuffer()
        poly.draw(["LINES", "TRIANGLES"]);
        requestAnimationFrame(ani);
    })();



    function createColor(count) {
        let tempArr = [];
        for (let i = 0; i < count; i++) {
            tempArr.push(1, 1, 1, 0.5);
        }
        return tempArr;
    }

    function addData(arr, eachCount1, newArr, eachCount2) {
        let tempArr = [];
        for (let i = 0; i < arr.length; i += eachCount1) {

            for (let j = i; j < (eachCount1 + i); j++) {
                tempArr.push(arr[j]);
            }

            let newArrIndex = i / eachCount1 * eachCount2;
            for (let j = 0; j < eachCount2; j++) {
                tempArr.push(newArr[newArrIndex + j])
            }
        }
        return tempArr;
    }


    function updateY(arr, offset = 0) {
        for (let i = 0; i < arr.length; i += 8) {
            const [x, z] = [arr[i], arr[i + 2]];
            const angZ = scalerZ(z);
            const Omega = 2;
            const a = Math.sin(angZ) * 0.1 + 0.03;
            const phi = scalerX(x) + offset;
            arr[i + 1] = SinFn(a, Omega, phi)(angZ);

            var b = (arr[i + 1] + 0.12954653691857204) / (0.12954653691857204 * 2);

            var colorArr = lib.gradientColor(minColor, maxColor, b);

            arr[i + 3] = colorArr[0] / 255;
            arr[i + 4] = colorArr[1] / 255;
            arr[i + 5] = colorArr[2] / 255;
        }
        return arr;
    }

    function SinFn(a, Omega, phi) {
        return function (x) {
            return a * Math.sin(Omega * x + phi);
        }
    }

    function createNodes() {
        let arr = [];
        let [x, y, z] = [0, 0, 0];
        for (let i = 0; i < (endLength / interval + 1) ** 2; i++) {
            arr.push(x, y, z);
            x += interval;
            if (x > endLength) {
                x = 0;
                z += interval;
            }
        }
        return arr;
    }

    function cssToGl(arr, glpos) {
        const glInterval = interval / endLength * gl;
        let tempArr = [];

        for (let i = 0; i < arr.length; i += 3) {
            tempArr.push((arr[i] / endLength) * (glpos * 2) - glpos);
            tempArr.push(arr[i + 1]);
            tempArr.push((arr[i + 2] / endLength) * (glpos * 2) - glpos);
        }
        return tempArr;
    }



}